/***************************************************************************//**
* \file cyhal_hw_types.h
*
* \brief
* Provides a struct definitions for configuration resources in the PDL.
*
********************************************************************************
* \copyright
* Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of Cypress Semiconductor Corporation
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

/**
* \addtogroup group_hal_impl CAT1 Implementation Specific
* \{
* This section provides details about the CAT1 implementation of the Cypress HAL.
* All information within this section is platform specific and is provided for reference.
* Portable application code should depend only on the APIs and types which are documented
* in the @ref group_hal section.
*
* \section group_hal_impl_mapping HAL Resource Hardware Mapping
* The following table shows a mapping of each HAL driver to the lower level firmware driver
* and the corresponding hardware resource. This is intended to help understand how the HAL
* is implemented for CAT1 and what features the underlying hardware supports.
*
* | HAL Resource       | PDL Driver(s)       | CAT1 Hardware                    |
* | ------------------ | ------------------- | -------------------------------- |
* | ADC                | cy_adc              | SAR ADC                          |
* | Clock              | cy_sysclk           | All clocks (system & peripheral) |
* | Comparator         | cy_ctb or cy_lpcomp | CTBm or LPComp                   |
* | CRC                | cy_crypto_core_crc  | Crypto                           |
* | DAC                | cy_ctdac            | DAC                              |
* | DMA                | cy_dma, cy_dmac     | DMA Controller                   |
* | EZ-I2C             | cy_scb_ezi2c        | SCB                              |
* | Flash              | cy_flash            | Flash                            |
* | GPIO               | cy_gpio             | GPIO                             |
* | Hardware Manager   | NA                  | NA                               |
* | I2C                | cy_scb_i2c          | SCB                              |
* | I2S                | cy_i2s              | I2S                              |
* | LPTimer            | cy_mcwdt            | MCWDT                            |
* | Opamp              | cy_ctb              | CTBm                             |
* | PDM/PCM            | cy_pdm_pcm          | PDM-PCM                          |
* | PWM                | cy_pwm              | TCPWM                            |
* | QSPI               | cy_smif             | QSPI (SMIF)                      |
* | Quadrature Decoder | cy_tcpwm_quaddec    | TCPWM                            |
* | RTC                | cy_rtc              | RTC                              |
* | SDHC               | cy_sd_host          | SD Host                          |
* | SDIO               | cy_sd_host, or NA   | SD Host, or UDB                  |
* | SPI                | cy_scb_spi          | SCB                              |
* | SysPM              | cy_syspm            | System Power Resources           |
* | System             | cy_syslib           | System Resources                 |
* | TDM                | cy_i2s              | I2S                              |
* | Timer              | cy_tcpwm_counter    | TCPWM                            |
* | TRNG               | cy_crypto_core_trng | Crypto                           |
* | UART               | cy_scb_uart         | SCB                              |
* | USB Device         | cy_usbfs_dev_drv    | USB-FS                           |
* | WDT                | cy_wdt              | WDT                              |
*
* \section group_hal_impl_errors Device Specific Errors
* Error codes generated by the low level level PDL driver all use module IDs starting
* with \ref CY_RSLT_MODULE_DRIVERS_PDL_BASE. The exact errors are documented for each
* driver in the
* <a href="https://infineon.github.io/mtb-pdl-cat1/pdl_api_reference_manual/html/index.html">
* mtb-pdl-cat1 documentation</a>.
*/

/**
* \addtogroup group_hal_impl_hw_types CAT1 Specific Hardware Types
* \{
* Aliases for types which are part of the public HAL interface but whose representations
* need to vary per HAL implementation
*/

#pragma once

#include "cy_pdl.h"
#include "cyhal_general_types.h"
#include "cyhal_hw_resources.h"
#include "cyhal_pin_package.h"
#include "cyhal_triggers.h"
#include <stdbool.h>

#if defined(CYHAL_UDB_SDIO)
    #include "SDIO_HOST.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if defined(COMPONENT_CAT1D)
#define CYHAL_TRIGGER_CPUSS_ZERO CYHAL_TRIGGER_M33SYSCPUSS_ZERO
#endif

#ifndef CYHAL_ISR_PRIORITY_DEFAULT
/** Priority that is applied by default to all drivers when initialized. Priorities can be
 * overridden on each driver as part of enabling events.
 */
#if (CORE == CM0P)
#define CYHAL_ISR_PRIORITY_DEFAULT  (3)
#else  // (CORE == CM0P)
#define CYHAL_ISR_PRIORITY_DEFAULT  (7)
#endif // (CORE == CM0P)
#endif

/**
* \cond INTERNAL
*/

#define CYHAL_ADC_IMPL_HEADER           "cyhal_adc_impl.h"      //!< Implementation specific header for ADC
#define CYHAL_DMA_IMPL_HEADER           "cyhal_dma_impl.h"      //!< Implementation specific header for DMA
#define CYHAL_CLOCK_IMPL_HEADER         "cyhal_clock_impl.h"    //!< Implementation specific header for Clocks
#define CYHAL_GPIO_IMPL_HEADER          "cyhal_gpio_impl.h"     //!< Implementation specific header for GPIO
#define CYHAL_PDMPCM_IMPL_HEADER        "cyhal_pdmpcm_impl.h"   //!< Implementation specific header for PDMPCM
#define CYHAL_I2S_IMPL_HEADER           "cyhal_i2s_impl.h"      //!< Implementation specific header for I2S
#define CYHAL_PWM_IMPL_HEADER           "cyhal_pwm_impl.h"      //!< Implementation specific header for PWM
#define CYHAL_QUADDEC_IMPL_HEADER       "cyhal_quaddec_impl.h"  //!< Implementation specific header for QUADDEC
#define CYHAL_SYSTEM_IMPL_HEADER        "cyhal_system_impl.h"   //!< Implementation specific header for System
#define CYHAL_SYSPM_IMPL_HEADER         "cyhal_syspm_impl.h"    //!< Implementation specific header for System Power Management
#define CYHAL_TDM_IMPL_HEADER           "cyhal_tdm_impl.h"      //!< Implementation specific header for TDM
#define CYHAL_TIMER_IMPL_HEADER         "cyhal_timer_impl.h"    //!< Implementation specific header for Timer
#define CYHAL_INTERCONNECT_IMPL_HEADER  "cyhal_interconnect_impl.h"     //!< Implementation specific header for Interconnect

#if defined(_CYHAL_DRIVER_AVAILABLE_CRYPTO)
#define CYHAL_CRC_IMPL_HEADER           "cyhal_crc_impl.h"      //!< Implementation specific header for CRC
#define CYHAL_TRNG_IMPL_HEADER          "cyhal_trng_impl.h"     //!< Implementation specific header for TRNG
#endif

#if defined(CYHAL_DRIVER_AVAILABLE_IPC)
#define CYHAL_IPC_IMPL_HEADER          "cyhal_ipc_impl.h"       //!< Implementation specific header for IPC
#endif

//TODO REMOVE this once PDL provides the missing items
#if defined(COMPONENT_CAT1B)
#include "cyhal_missing_pdl.h"
#endif

/** \endcond */

/** Callbacks for Sleep and Deepsleep APIs */
#define cyhal_system_callback_t cy_stc_syspm_callback_t

/** @brief Event callback data object */
typedef struct {
    cy_israddress                       callback;
    void*                               callback_arg;
} cyhal_event_callback_data_t;

/**
  * @brief Store information about buffer
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
    union
    {
        void     *v;
        uint8_t  *u8;
        uint16_t *u16;
        uint32_t *u32;
    } addr;
    uint32_t size;
} _cyhal_buffer_info_t;

/**
 * @brief Shared data between timer/counter and PWM
 *
 * Application code should not rely on the specific content of this struct.
 * They are considered an implementation detail which is subject to change
 * between platforms and/or HAL releases.
 */
typedef struct {
#ifdef CY_IP_MXTCPWM
    bool                                owned_by_configurator;
    bool                                presleep_state;
    TCPWM_Type*                         base;
    cyhal_resource_inst_t               resource;
    cyhal_clock_t                       clock;
    bool                                dedicated_clock;
    uint32_t                            clock_hz;
    cyhal_event_callback_data_t         callback_data;
    /* Bits to clear from the interrupt mask during the next ISR */
    uint32_t                            clear_intr_mask;
#if defined(CY_IP_MXPERI_TR) || defined(CY_IP_MXSPERI)
    cyhal_source_t                      inputs[5];
#endif
#else
    void *empty;
#endif
} cyhal_tcpwm_t;

/* This is presented out of order because many other structs depend on it */
/**
  * @brief DMA object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_M4CPUSS_DMA) || defined(CY_IP_M7CPUSS_DMA) || defined(CY_IP_MXAHBDMAC) || defined(CY_IP_MXDW) || defined(CY_IP_MXSAXIDMAC)
    cyhal_resource_inst_t               resource;
    #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
    CY_ALIGN(__SCB_DCACHE_LINE_SIZE)
    #endif
    union
    {
#if defined(CY_IP_M4CPUSS_DMA) || defined(CY_IP_M7CPUSS_DMA) || defined(CY_IP_MXDW)
        cy_stc_dma_channel_config_t     dw;
#endif
#if defined(CY_IP_MXSAXIDMAC)
        cy_stc_axidmac_channel_config_t dmac;
#elif defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
        cy_stc_dmac_channel_config_t    dmac;
#endif
    } channel_config;
    #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
    CY_ALIGN(__SCB_DCACHE_LINE_SIZE)
    #endif
    union
    {
#if defined(CY_IP_M4CPUSS_DMA) || defined(CY_IP_M7CPUSS_DMA) || defined(CY_IP_MXDW)
        cy_stc_dma_descriptor_config_t  dw;
#endif
#if defined(CY_IP_MXSAXIDMAC)
        cy_stc_axidmac_descriptor_config_t dmac;
#elif defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
        cy_stc_dmac_descriptor_config_t dmac;
#endif
    } descriptor_config;
    #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
    CY_ALIGN(__SCB_DCACHE_LINE_SIZE)
    #endif
    union
    {
#if defined(CY_IP_M4CPUSS_DMA) || defined(CY_IP_M7CPUSS_DMA) || defined(CY_IP_MXDW)
        cy_stc_dma_descriptor_t         dw;
#endif
#if defined(CY_IP_MXSAXIDMAC)
        cy_stc_axidmac_descriptor_t     dmac;
#elif defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
        cy_stc_dmac_descriptor_t        dmac;
#endif
    } descriptor;
    uint16_t                            expected_bursts;
    uint32_t/* cyhal_dma_direction_t */ direction;
    uint32_t                            irq_cause;
    cyhal_event_callback_data_t         callback_data;
    cyhal_source_t                      source;
    bool                                owned_by_configurator;
#else
    void *empty;
#endif
} cyhal_dma_t;

/**
  * @brief DMA configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_DMA
    const cyhal_resource_inst_t*                    resource;
    struct
    {
        union
        {
#if defined(CY_IP_M4CPUSS_DMA) || defined(CY_IP_M7CPUSS_DMA) || defined(CY_IP_MXDW)
            cy_stc_dma_channel_config_t const*      dw_channel_config;
#endif
#if defined(CY_IP_MXSAXIDMAC)
            cy_stc_axidmac_channel_config_t const*  dmac_channel_config;
#elif defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
            cy_stc_dmac_channel_config_t const*     dmac_channel_config;
#endif
        };
        union
        {
#if defined(CY_IP_M4CPUSS_DMA) || defined(CY_IP_M7CPUSS_DMA) || defined(CY_IP_MXDW)
            cy_stc_dma_descriptor_config_t const*   dw_descriptor_config;
#endif
#if defined(CY_IP_MXSAXIDMAC)
            cy_stc_axidmac_descriptor_config_t const*  dmac_descriptor_config;
#elif defined(CY_IP_M4CPUSS_DMAC) || defined(CY_IP_M7CPUSS_DMAC) || defined(CY_IP_MXAHBDMAC)
            cy_stc_dmac_descriptor_config_t const*  dmac_descriptor_config;
#endif
        };
    };
#else
    void *empty;
#endif /* CYHAL_DRIVER_AVAILABLE_DMA */
} cyhal_dma_configurator_t;

struct _cyhal_audioss_s;

/**
  * @brief Interface to abstract away the driver-specific differences between TDM and I2S
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct
{
#if defined(CY_IP_MXAUDIOSS)
    /** Convert a PDL-level interrupt cause to a HAL-level event */
    uint32_t (*convert_interrupt_cause)(uint32_t pdl_event);
    /** Convert a HAL-level event to a PDL-level interrupt cause */
    uint32_t (*convert_to_pdl)(uint32_t hal_event);
#elif defined(CY_IP_MXTDM)
    /** Convert a PDL-level interrupt cause to a HAL-level event */
    uint32_t (*convert_interrupt_cause)(uint32_t pdl_event, bool is_tx);
    /** Convert a HAL-level event to a PDL-level interrupt cause */
    uint32_t (*convert_to_pdl)(uint32_t hal_event, bool is_tx);
#endif
    /** Invoke the user callback with the specified HAL event.
     * Only called after the user callback has been verified to not be null. */
    void     (*invoke_user_callback)(struct _cyhal_audioss_s* obj, uint32_t hal_event);
    /** HAL event mask that represents the empty state */
    uint32_t event_mask_empty;
    /** HAL event mask that represents the half empty state */
    uint32_t event_mask_half_empty;
    /** HAL event mask that represents the full state */
    uint32_t event_mask_full;
    /** HAL event mask that represents the half full state */
    uint32_t event_mask_half_full;
    /** HAL event mask that represents async rx complete */
    uint32_t event_rx_complete;
    /** HAL event mask that represents async tx complete */
    uint32_t event_tx_complete;
    /** Error code for invalid pin */
    cy_rslt_t err_invalid_pin;
    /** Error code for invalid argument */
    cy_rslt_t err_invalid_arg;
    /** Error code for invalid clock frequency */
    cy_rslt_t err_clock;
    /** Error code for configuration not supported */
    cy_rslt_t err_not_supported;
} _cyhal_audioss_interface_t;

/**
  * @brief Shared data between i2s and tdm
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct _cyhal_audioss_s { /* Explicit name to enable forward declaration */
#if defined(CY_IP_MXAUDIOSS) || defined(CY_IP_MXTDM)
    bool                            owned_by_configurator;
#if defined(CY_IP_MXAUDIOSS)
    I2S_Type                        *base;
#elif defined(CY_IP_MXTDM)
    /* None of the PDL APIs actually want a bare TDM_Type */
    TDM_STRUCT_Type                 *base;
#endif
    cyhal_resource_inst_t           resource;
    cyhal_gpio_t                    pin_tx_sck;
    cyhal_gpio_t                    pin_tx_ws;
    cyhal_gpio_t                    pin_tx_sdo;
    cyhal_gpio_t                    pin_rx_sck;
    cyhal_gpio_t                    pin_rx_mclk;
    cyhal_gpio_t                    pin_rx_ws;
    cyhal_gpio_t                    pin_rx_sdi;
    cyhal_gpio_t                    pin_tx_mclk;
    uint8_t                         user_fifo_level_rx;
    uint32_t                        mclk_hz_rx;
    uint8_t                         channel_length_rx;
    uint8_t                         word_length_rx;
    uint32_t                        mclk_hz_tx;
    uint8_t                         channel_length_tx;
    uint8_t                         word_length_tx;
    cyhal_clock_t                   clock;
    bool                            is_clock_owned;
    uint16_t                        user_enabled_events;
    cyhal_event_callback_data_t     callback_data;
    cyhal_async_mode_t              async_mode;
    uint8_t                         async_dma_priority;
    cyhal_dma_t                     tx_dma;
    cyhal_dma_t                     rx_dma;
    // Note: When the async DMA mode is in use, these variables will always reflect the state
    // that the transfer will be in after the in-progress DMA transfer, if any, is complete
    volatile const void             *async_tx_buff;
    volatile size_t                 async_tx_length;
    volatile void                   *async_rx_buff;
    volatile size_t                 async_rx_length;
    volatile bool                   pm_transition_ready;
    cyhal_syspm_callback_data_t     pm_callback;
    const _cyhal_audioss_interface_t *interface;
#else
    void *empty;
#endif
} _cyhal_audioss_t;

/**
  * @brief Shared I2S/TDM configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_TDM || CYHAL_DRIVER_AVAILABLE_I2S
    const cyhal_resource_inst_t*            resource;
#if defined(CY_IP_MXAUDIOSS)
    const cy_stc_i2s_config_t*              config;
#elif defined(CY_IP_MXTDM)
    const cy_stc_tdm_config_t*              config;
#endif
    const cyhal_clock_t *                   clock;
    uint32_t                                mclk_hz_rx; /* Must be 0 is mclk is not in use for this direction */
    uint32_t                                mclk_hz_tx; /* Must be 0 is mclk is not in use for this direction */
#else
    void *empty;
#endif /* CYHAL_DRIVER_AVAILABLE_TDM || CYHAL_DRIVER_AVAILABLE_I2S */
} _cyhal_audioss_configurator_t;

struct _cyhal_adc_channel_s;

/* Maximum number of channels across all ADC instances. For CAT1A this is provided by the PDL, for CAT1C we have to compute this */
#if defined(CY_IP_MXS40EPASS_ESAR)
    #if (((CY_IP_MXS40EPASS_ESAR_INSTANCES < 2) || (PASS_SAR_SLICE_NR0_SAR_SAR_CHAN_NR > PASS_SAR_SLICE_NR1_SAR_SAR_CHAN_NR)) \
      && ((CY_IP_MXS40EPASS_ESAR_INSTANCES < 3) || (PASS_SAR_SLICE_NR0_SAR_SAR_CHAN_NR > PASS_SAR_SLICE_NR2_SAR_SAR_CHAN_NR)))
        #define CY_SAR_MAX_NUM_CHANNELS (PASS_SAR_SLICE_NR0_SAR_SAR_CHAN_NR)
    #elif ((CY_IP_MXS40EPASS_ESAR_INSTANCES < 2) /* If we got to this point, we know neither 0 isn't the max */ \
      && (CY_IP_MXS40EPASS_ESAR_INSTANCES < 3 || (PASS_SAR_SLICE_NR1_SAR_SAR_CHAN_NR > PASS_SAR_SLICE_NR2_SAR_SAR_CHAN_NR)))
        #define CY_SAR_MAX_NUM_CHANNELS (PASS_SAR_SLICE_NR1_SAR_SAR_CHAN_NR)
    #elif (CY_IP_MXS40EPASS_ESAR_INSTANCES < 4) /* If we got to this point, we know neither 0 nor 1 is the max */
        #define CY_SAR_MAX_NUM_CHANNELS (PASS_SAR_SLICE_NR2_SAR_SAR_CHAN_NR)
    #else
        #error "Unhandled ADC instance count"
    #endif
#endif
/**
  * @brief ADC object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXS40PASS_SAR) || defined(CY_IP_MXS40EPASS_ESAR) || defined(CY_IP_MXS40ADCMIC_INSTANCES)
    bool                                owned_by_configurator;
#if defined(CY_IP_MXS40PASS_SAR) || defined(CY_IP_MXS40EPASS_ESAR)
#if defined(CY_IP_MXS40PASS_SAR)
    SAR_Type*                           base;
#else
    PASS_SAR_Type*                      base;
    uint16_t                            average_count; /* This is set per channel on this hardware */
    bool                                average_is_accumulate;
#endif
    struct _cyhal_adc_channel_s*        channel_config[CY_SAR_MAX_NUM_CHANNELS];
#elif defined(CY_IP_MXS40ADCMIC_INSTANCES)
    MXS40ADCMIC_Type*                   base;
    /* When doing a full scan, which channel are we on */
    uint8_t                             current_channel_index;
    /* We implement multi-channel sequencing in firmware; there's no fixed channel count specified
     * in hardware. So size the array based on the number of input pins that are connected */
    struct _cyhal_adc_channel_s*        channel_config[sizeof(cyhal_pin_map_adcmic_gpio_adc_in) / sizeof(cyhal_pin_map_adcmic_gpio_adc_in[0])];
    cy_stc_adcmic_context_t             pdl_context;
#endif
    cyhal_resource_inst_t               resource;
    cyhal_clock_t                       clock;
    bool                                dedicated_clock;
    /* Has at least one conversion completed since the last configuration change */
    volatile bool                       conversion_complete;
#if defined(CY_IP_MXS40PASS_SAR)
    bool                                stop_after_scan;
#endif
    uint8_t                             user_enabled_events;
    cyhal_event_callback_data_t         callback_data;
    /* Always updated to contain the location where the next result should be stored */
    int32_t                             *async_buff_next;
    bool                                async_transfer_in_uv; /* Default is counts */
    /* Only decremented after all elements from a scan have been copied into async_buff */
    size_t                              async_scans_remaining;
#if defined(CY_IP_MXS40PASS_SAR) || defined(CY_IP_MXS40EPASS_ESAR)
    /* ADCMIC is always continuously scanning and only supports SW-based async transfers */
    bool                                continuous_scanning;
    cyhal_async_mode_t                  async_mode;
    cyhal_dma_t                         dma;
    cyhal_source_t                      source; /* SAR-only; ADCMIC has no useful triggers in DC mode */
    int32_t                             *async_buff_orig;
#if defined(CY_IP_MXS40EPASS_ESAR)
    bool                                vbg_chan_inited;
    uint16_t                            vbg_last_value;
#endif /* defined(CY_IP_MXS40EPASS_ESAR) */
#endif
#else
    void *empty;
#endif /* defined(CY_IP_MXS40PASS_SAR) || defined(CY_IP_MXS40EPASS_ESAR) || defined(CY_IP_MXS40ADCMIC_INSTANCES) */
} cyhal_adc_t;

/**
  * @brief ADC configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_ADC
    const cyhal_resource_inst_t*        resource;
#if defined(CY_IP_MXS40PASS_SAR)
    cy_stc_sar_config_t const*          config;
#elif defined(CY_IP_MXS40EPASS_ESAR_INSTANCES)
    cy_stc_sar2_config_t const*          config;
#elif defined(CY_IP_MXS40ADCMIC_INSTANCES)
    cy_stc_adcmic_config_t const*       config;
#endif
    const cyhal_clock_t *               clock;
    uint8_t                             num_channels;
    const uint32_t*                     achieved_acquisition_time; /* length num_channels */
    /* Pins are deliberately omitted from this struct. The configurator supports routing
     * from arbitrary sources that aren't necessarily pins. The HAL only needs to know what
     * the pins are for the purposes of reservation, freeing, and routing - all of which the
     * configurators take care of in this flow */
#else
     void *empty;
#endif
} cyhal_adc_configurator_t;

/**
  * @brief ADC channel object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct _cyhal_adc_channel_s { /* Struct given an explicit name to make the forward declaration above work */
#if defined(CY_IP_MXS40PASS_SAR) || defined(CY_IP_MXS40EPASS_ESAR) || defined(CY_IP_MXS40ADCMIC_INSTANCES)
    cyhal_adc_t*                        adc;
    cyhal_gpio_t                        vplus;
    uint8_t                             channel_idx;
#if defined(CY_IP_MXS40ADCMIC_INSTANCES)
    /* ADCMIC only supports single-ended channels at a fixed sample rate */
    cy_en_adcmic_dc_channel_t           channel_sel;
    bool                                enabled;
#elif defined(CY_IP_MXS40PASS_SAR) || defined(CY_IP_MXS40EPASS_ESAR)
#if defined(CY_IP_MXS40PASS_SAR)
    cyhal_gpio_t                        vminus;
#elif defined(CY_IP_MXS40EPASS_ESAR_INSTANCES)
    bool                                avg_enabled;
#endif
    /* EPASS only supports single-ended channels */
    uint32_t                            minimum_acquisition_ns;
#endif
#else
    void *empty;
#endif
} cyhal_adc_channel_t;

/** @brief Comparator object */
typedef struct {
#if defined(CY_IP_MXLPCOMP_INSTANCES) || defined(CY_IP_MXS40PASS_CTB_INSTANCES)
    bool                                owned_by_configurator;
    cyhal_resource_inst_t               resource;
    union
    {
#if defined(CY_IP_MXS40PASS_CTB_INSTANCES)
        CTBM_Type                       *base_ctb;
#endif
#if defined(CY_IP_MXLPCOMP_INSTANCES)
        LPCOMP_Type                     *base_lpcomp;
#endif
    };
    cyhal_gpio_t                        pin_vin_p;
    cyhal_gpio_t                        pin_vin_m;
    cyhal_gpio_t                        pin_out;
    cyhal_event_callback_data_t         callback_data;
    uint32_t                            irq_cause;
#else
    void *empty;
#endif
} cyhal_comp_t;

/**
  * @brief Comp configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_COMP
    const cyhal_resource_inst_t*        resource;
    union
    {
    #if _CYHAL_DRIVER_AVAILABLE_COMP_LP
        const cy_stc_lpcomp_config_t *lpcomp;
    #endif
    #if _CYHAL_DRIVER_AVAILABLE_COMP_CTB
        const cy_stc_ctb_opamp_config_t *opamp;
    #endif
    };
    /* No GPIOs specified. The configurator could have routed from a non-preferred
     * GPIO, or from another non-GPIO on-chip source. */
#else
    void *empty;
#endif
} cyhal_comp_configurator_t;

/**
  * @brief CRC object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXCRYPTO_INSTANCES) || defined(CPUSS_CRYPTO_PRESENT)
    CRYPTO_Type*                        base;
    cyhal_resource_inst_t               resource;
    uint32_t                            crc_width;
#else
    void *empty;
#endif
} cyhal_crc_t;

/**
  * @brief DAC object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#ifdef CY_IP_MXS40PASS_CTDAC
    bool                                owned_by_configurator;
    CTDAC_Type*                         base_dac;
    CTBM_Type*                          base_opamp;
    cyhal_resource_inst_t               resource_dac;
    cyhal_resource_inst_t               resource_opamp;
    cyhal_resource_inst_t               resource_aref_opamp;
    cyhal_gpio_t                        pin;
#else
    void *empty;
#endif
} cyhal_dac_t;

/**
  * @brief DAC configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_DAC
    const cyhal_resource_inst_t*        resource;
    const cy_stc_ctdac_config_t*        config;
#else
    void *empty;
#endif /* CYHAL_DRIVER_AVAILABLE_DAC */
} cyhal_dac_configurator_t;

/**
  * @brief OPAMP object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXS40PASS_CTB_INSTANCES)
    bool                                owned_by_configurator;
    CTBM_Type*                          base;
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        pin_vin_p;
    cyhal_gpio_t                        pin_vin_m;
    cyhal_gpio_t                        pin_vout;
    bool                                is_init_success;
#else
    void *empty;
#endif
} cyhal_opamp_t;

/**
  * @brief Opamp configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_OPAMP
    const cyhal_resource_inst_t*        resource;
    const cy_stc_ctb_opamp_config_t*    config;
    /* No GPIOs specified. The configurator could have routed from a non-preferred
     * GPIO, or from another non-GPIO on-chip source. */
#else
    void *empty;
#endif
} cyhal_opamp_configurator_t;

/**
  * @brief Flash object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
    void *empty;
} cyhal_flash_t;

/**
  * @brief I2C object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB)
    CySCB_Type*                         base;
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        pin_sda;
    cyhal_gpio_t                        pin_scl;
    cyhal_clock_t                       clock;
    bool                                is_clock_owned;
    cy_stc_scb_i2c_context_t            context;
    cy_stc_scb_i2c_master_xfer_config_t rx_config;
    cy_stc_scb_i2c_master_xfer_config_t tx_config;
    uint32_t                            irq_cause;
    uint8_t                             addr_irq_cause;
    uint16_t                            pending;
    bool                                op_in_callback;
    _cyhal_buffer_info_t                rx_slave_buff;
    _cyhal_buffer_info_t                tx_slave_buff;
    cyhal_event_callback_data_t         callback_data;
    cyhal_event_callback_data_t         addr_callback_data;
    bool                                dc_configured;
#else
    void *empty;
#endif
} cyhal_i2c_t;

/**
  * @brief I2C configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB)
    const cyhal_resource_inst_t*            resource;
    const cy_stc_scb_i2c_config_t*          config;
    const cyhal_clock_t*                    clock;
#else
    void *empty;
#endif /* defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB) */
} cyhal_i2c_configurator_t;

/**
  * @brief EZI2C object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB)
    CySCB_Type*                         base;
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        pin_sda;
    cyhal_gpio_t                        pin_scl;
    cyhal_clock_t                       clock;
    bool                                is_clock_owned;
    cy_stc_scb_ezi2c_context_t          context;
    uint32_t                            irq_cause;
    cyhal_event_callback_data_t         callback_data;
    bool                                two_addresses;
    bool                                dc_configured;
#else
    void *empty;
#endif
} cyhal_ezi2c_t;

/**
  * @brief EZI2C configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB)
    const cyhal_resource_inst_t*            resource;
    const cy_stc_scb_ezi2c_config_t*        config;
    const cyhal_clock_t*                    clock;
#else
    void *empty;
#endif /* defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB) */
} cyhal_ezi2c_configurator_t;

/**
  * @brief I2S object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef _cyhal_audioss_t cyhal_i2s_t;

/**
  * @brief I2S configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef _cyhal_audioss_configurator_t cyhal_i2s_configurator_t;

/** @brief IPC object */
typedef struct cyhal_ipc_s {
#if defined(IPC) || defined(CY_IP_MXIPC)
    bool                                sema_preemptable;
    uint32_t                            sema_number;
    struct cyhal_ipc_queue_s*           queue_obj;
    uint16_t                            user_events;
    /* events, that were already processed in callback */
    uint32_t                            processed_events;
    cyhal_event_callback_data_t         callback_data;
    struct cyhal_ipc_s*                 prev_object;
#if defined(CY_RTOS_AWARE) || defined(COMPONENT_RTOS_AWARE)
    void*                               rtos_sema;
#endif /* defined(CY_RTOS_AWARE) || defined(COMPONENT_RTOS_AWARE) */
#else
    void *empty;
#endif
} cyhal_ipc_t;

/**
  * @brief KeyScan object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined (CY_IP_MXKEYSCAN)
    MXKEYSCAN_Type*                     base;
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        rows[MXKEYSCAN_NUM_ROWS_IN];
    cyhal_gpio_t                        columns[MXKEYSCAN_NUM_COLS_OUT];
    cyhal_clock_t                       clock;
    bool                                is_clock_owned;
    cy_stc_keyscan_context_t            context;
    uint32_t                            irq_cause;
    cyhal_event_callback_data_t         callback_data;
    bool                                dc_configured;
#else
    void *empty;
#endif
} cyhal_keyscan_t;

/**
  * @brief KeyScan configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#if defined (CY_IP_MXKEYSCAN)
    const cyhal_resource_inst_t*            resource;
    /* keyscan PDL config is not const here because the config argument to Cy_Keyscan_Init is not const */
    cy_stc_ks_config_t*                     config;
    const cyhal_clock_t*                    clock;
#else
    void *empty;
#endif /* defined (CY_IP_MXKEYSCAN) */
} cyhal_keyscan_configurator_t;

/**
  * @brief LPTIMER object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 3))
    MCWDT_Type                          *base;
    cy_en_mcwdtctr_t                    counter;
    volatile uint32_t                   offset;
    volatile uint32_t                   final_time;
#else
    MCWDT_STRUCT_Type                   *base;
#endif
    cyhal_resource_inst_t               resource;
    cyhal_event_callback_data_t         callback_data;
    bool                                clear_int_mask;
    uint8_t                             isr_instruction;
} cyhal_lptimer_t;

/**
  * @brief PDM-PCM object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if !defined(COMPONENT_CAT1C)
#if defined(CY_IP_MXAUDIOSS_INSTANCES) || defined(CY_IP_MXTDM_INSTANCES)
    bool                                owned_by_configurator;
    PDM_Type                            *base;
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        pin_data;
    cyhal_gpio_t                        pin_clk;
    cyhal_clock_t                       clock;
    bool                                is_clock_owned;
    /* Number of entries in the fifo when the trigger fires - i.e. one greater than the value in the register */
    uint8_t                             user_trigger_level;
    /** User requested irq, see cyhal_pdm_pcm_event_t */
    uint32_t                            irq_cause;
    cyhal_event_callback_data_t         callback_data;
    uint8_t                             word_size;
    cyhal_dma_t                         dma;
#if defined(CY_IP_MXPDM)
    cyhal_dma_t                         dma_paired;
#endif
    volatile bool                       stabilized;
    volatile bool                       pm_transition_ready;
    cyhal_syspm_callback_data_t         pm_callback;
    void                                *async_buffer;
    size_t                              async_read_remaining;
#else
    void *empty;
#endif
#else
    void *empty;
#endif
} cyhal_pdm_pcm_t;

/**
  * @brief PDM-PCM configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#if !defined(COMPONENT_CAT1C)
#if defined(CY_IP_MXAUDIOSS_INSTANCES) || defined(CY_IP_MXTDM_INSTANCES)
    const cyhal_resource_inst_t*            resource;
#if defined(CY_IP_MXAUDIOSS_INSTANCES)
    const cy_stc_pdm_pcm_config_t*          config;
#elif defined(CY_IP_MXTDM_INSTANCES)
    const cy_stc_pdm_pcm_config_v2_t*       config;
    const cy_stc_pdm_pcm_channel_config_t*  chan_config;
#endif
    const cyhal_clock_t*                    clock;
#else
    void *empty;
#endif
#else
    void *empty;
#endif
} cyhal_pdm_pcm_configurator_t;

/**
  * @brief PWM object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#ifdef CY_IP_MXTCPWM
    cyhal_tcpwm_t                       tcpwm;
    cyhal_gpio_t                        pin;
    cyhal_gpio_t                        pin_compl;
    bool                                dead_time_set;
#else
    void *empty;
#endif
} cyhal_pwm_t;

/**
  * @brief PWM configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_PWM
    const cyhal_resource_inst_t*        resource;
    cy_stc_tcpwm_pwm_config_t const*    config;
    const cyhal_clock_t *               clock;
#else
    void *empty;
#endif /* CYHAL_DRIVER_AVAILABLE_PWM */
} cyhal_pwm_configurator_t;

/**
  * @brief QSPI object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#ifdef CY_IP_MXSMIF
    SMIF_Type*                          base;
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        pin_sclk;
    en_hsiom_sel_t                      saved_sclk_hsiom;
    cyhal_gpio_t                        pin_io[8];
    en_hsiom_sel_t                      saved_io_hsiom[8];
    cyhal_gpio_t                        pin_ssel[SMIF_CHIP_TOP_SPI_SEL_NR];
    en_hsiom_sel_t                      saved_ssel_hsiom[SMIF_CHIP_TOP_SPI_SEL_NR];
    /* Active slave select */
    cy_en_smif_slave_select_t           slave_select;
    cyhal_clock_t                       clock;
    bool                                is_clock_owned;
    uint8_t                             mode;
    cy_stc_smif_context_t               context;
    uint32_t                            irq_cause;
    cyhal_event_callback_data_t         callback_data;
    cyhal_syspm_callback_data_t         pm_callback;
    bool                                pm_transition_pending;
    bool                                dc_configured;
#else
    void *empty;
#endif /* ifdef CY_IP_MXSMIF */
} cyhal_qspi_t;

/**
  * @brief QSPI configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#ifdef CY_IP_MXSMIF
    const cyhal_resource_inst_t*            resource;
    const cy_stc_smif_config_t*             config;
    cyhal_clock_t*                          clock;
    struct
    {
        cyhal_gpio_t                        sclk;
        cyhal_gpio_t                        ssel[4];
        cyhal_gpio_t                        io[8];
    } gpios;
    /* Bit representation of currently not supported interrupts:
        Bit 5 : Memory Mode Alignment Error
        Bit 4 : RX Data FIFO Underflow
        Bit 3 : TX Command FIFO Overflow
        Bit 2 : TX Data FIFO Overflow
        Bit 1 : RX FIFO Level Trigger
        Bit 0 : TX FIFO Level Trigger
    */
    uint8_t                                 irqs;
    /* Bit representation of DMA triggers activation indicators:
        Bit 1 : RX Trigger Output activated in configurator
        Bit 0 : TX Trigger Output activated in configurator
    */
    uint8_t                                 dmas;
#else
    void *empty;
#endif /* defined(CY_IP_MXSMIF) */
} cyhal_qspi_configurator_t;

/**
  * @brief Quadrature Decoder object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#ifdef CY_IP_MXTCPWM
    cyhal_tcpwm_t                       tcpwm;
    cyhal_gpio_t                        phi_a;
    cyhal_gpio_t                        phi_b;
    cyhal_gpio_t                        index;
    uint32_t                            last_counter_value;
#else
    void *empty;
#endif
} cyhal_quaddec_t;

/**
  * @brief Quadrature Decoder configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_QUADDEC
    const cyhal_resource_inst_t*            resource;
    const cy_stc_tcpwm_quaddec_config_t*    config;
    const cyhal_clock_t *                   clock;
#else
    void *empty;
#endif /* CYHAL_DRIVER_AVAILABLE_QUADDEC */
} cyhal_quaddec_configurator_t;

/**
  * @brief RNG object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXCRYPTO_INSTANCES) || defined(CPUSS_CRYPTO_PRESENT)
    CRYPTO_Type*                        base;
    cyhal_resource_inst_t               resource;
#else
    void *empty;
#endif
} cyhal_trng_t;

/**
  * @brief RTC object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXS40SRSS) || defined(CY_IP_MXS40SSRSS)
    cy_stc_rtc_dst_t                    dst;
#else
    void *empty;
#endif
} cyhal_rtc_t;

/**
  * @brief RTC configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_RTC
    const cyhal_resource_inst_t*        resource;
    cy_stc_rtc_config_t const*          config;
    cy_stc_rtc_dst_t const*             dst_config;
#else
    void *empty;
#endif /* CYHAL_DRIVER_AVAILABLE_RTC */
} cyhal_rtc_configurator_t;

#if defined(CY_IP_MXSDHC)

/**
 * Data transfer status on SDHC/SDIO
 */
typedef enum
{
    /** No data transfer in progress */
    _CYHAL_SDXX_NOT_RUNNING = 0x0,
    /** Waiting for a command to complete */
    _CYHAL_SDXX_WAIT_CMD_COMPLETE = 0x1,
    /** Waiting for a transfer to complete */
    _CYHAL_SDXX_WAIT_XFER_COMPLETE = 0x2,
    /** Waiting for completion of both a command and a transfer */
    _CYHAL_SDXX_WAIT_BOTH = _CYHAL_SDXX_WAIT_CMD_COMPLETE | _CYHAL_SDXX_WAIT_XFER_COMPLETE
} _cyhal_sdxx_data_transfer_status_t;

/**
 * Contains common members between SDHC and SDIO
 */
typedef struct {
    bool                                is_sdio;
    void*                               obj;

    SDHC_Type*                          base;
    cyhal_resource_inst_t               resource;
    cy_stc_sd_host_context_t            context;
    cyhal_clock_t                       clock;

    bool                                emmc;
    cy_en_sd_host_dma_type_t            dma_type;
    uint32_t                            adma_descriptor_tbl[2];
    _cyhal_sdxx_data_transfer_status_t  data_transfer_status;

    cyhal_gpio_t                        pin_clk;
    cyhal_gpio_t                        pin_cmd;
    cyhal_gpio_t                        pin_io_vol_sel;
    bool                                low_voltage_io_set;

    uint32_t                            irq_cause;
    cyhal_event_callback_data_t         callback_data;

    bool                                pm_transition_pending;
    cyhal_syspm_callback_data_t         pm_callback_data;
    /* whether the block is configured by device-configurator (true)
    *  or by user via HAL API (false) */
    bool                                dc_configured;
    bool                                clock_owned;
} _cyhal_sdxx_t;

#endif /* defined(CY_IP_MXSDHC) */

/**
  * @brief SDHC object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSDHC)
    _cyhal_sdxx_t                       sdxx;

    uint8_t                             bus_width;
    bool                                enable_led_control;
    /* TOUT setting of SDHC block */
    uint8_t                             data_timeout_tout;
    bool                                data_timeout_auto_reconfig;
    /* Desired by user data timeout in card clocks */
    uint32_t                            data_timeout_card_clocks_user;
    cyhal_gpio_t                        pin_data[8];
    cyhal_gpio_t                        pin_card_detect;
    cyhal_gpio_t                        pin_card_pwr_en;
    cyhal_gpio_t                        pin_card_mech_write_prot;
    cyhal_gpio_t                        pin_led_ctrl;
    cyhal_gpio_t                        pin_emmc_reset;
    bool                                low_voltage_io_desired;
    uint32_t                            bus_frequency_hz;
    /* Frequency of HF clock, that provided to SDHC block */
    uint32_t                            block_source_freq_hz;
    /** This needs to mirror cyhal_gpio_callback_data_t, which can't be referenced directly. */
    struct cyhal_sdhc_t_gpio_cb
    {
        void*           callback;
        void*           callback_arg;
        void*           next;
        cyhal_gpio_t    pin;
    }                                   card_detect_cb;
    /* card detect GPIO callback enabled */
    bool                                cd_gpio_cb_enabled;
    uint16_t                            emmc_generic_cmd6_time_ms;
#else
    void *empty;
#endif /* defined(CY_IP_MXSDHC) */
} cyhal_sdhc_t;

/**
  * @brief SDHC configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSDHC)
    const cyhal_resource_inst_t*            resource;
    const cy_stc_sd_host_init_config_t*     host_config;
    cy_stc_sd_host_sd_card_config_t*        card_config;
    cyhal_clock_t*                          clock;
    struct
    {
        cyhal_gpio_t                        clk;
        cyhal_gpio_t                        cmd;
        cyhal_gpio_t                        data[8];
        cyhal_gpio_t                        card_detect;
        cyhal_gpio_t                        io_volt_sel;
        cyhal_gpio_t                        card_pwr_en;
        cyhal_gpio_t                        card_mech_write_prot;
        cyhal_gpio_t                        led_ctrl;
        cyhal_gpio_t                        emmc_reset;
    } gpios;
#else
    void *empty;
#endif /* defined(CY_IP_MXSDHC) */
} cyhal_sdhc_configurator_t;

/**
  * @brief SDIO object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSDHC)
    _cyhal_sdxx_t                       sdxx;
    /* whether the block is configured by device-configurator (true)
    *  or by user via HAL API (false) */
    bool                                dc_configured;
    bool                                clock_owned;
#elif defined(CYHAL_UDB_SDIO)
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        pin_clk;
    cyhal_gpio_t                        pin_cmd;

    uint32_t                            irq_cause;

    bool                                pm_transition_pending;
    cyhal_syspm_callback_data_t         pm_callback_data;
#endif /* defined(CYHAL_IP_MXSDHC) */

#if defined(CY_IP_MXSDHC) || defined(CYHAL_UDB_SDIO)
    cyhal_gpio_t                        pin_data0;
    cyhal_gpio_t                        pin_data1;
    cyhal_gpio_t                        pin_data2;
    cyhal_gpio_t                        pin_data3;

    uint32_t                            frequencyhal_hz;
    uint16_t                            block_size;

    uint32_t                            events;
#else
    void *empty;
#endif /* defined(CY_IP_MXSDHC) || defined(CYHAL_UDB_SDIO) */
} cyhal_sdio_t;

/**
  * @brief SDIO configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSDHC)
    const cyhal_resource_inst_t*            resource;
    const cy_stc_sd_host_init_config_t*     host_config;
    cy_stc_sd_host_sd_card_config_t*        card_config;
    cyhal_clock_t*                          clock;
    struct
    {
        cyhal_gpio_t                        clk;
        cyhal_gpio_t                        cmd;
        cyhal_gpio_t                        data[4];
    } gpios;
#else
    void *empty;
#endif /* defined(CY_IP_MXSDHC) */
} cyhal_sdio_configurator_t;

/**
  * @brief SPI object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB)
    CySCB_Type*                         base;
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        pin_miso;
    cyhal_gpio_t                        pin_mosi;
    cyhal_gpio_t                        pin_sclk;
    cyhal_gpio_t                        pin_ssel[4];
    cy_en_scb_spi_polarity_t            ssel_pol[4];
    uint8_t                             active_ssel;
    cyhal_clock_t                       clock;
    cy_en_scb_spi_sclk_mode_t           clk_mode;
    uint8_t                             mode;
    uint8_t                             data_bits;
    bool                                is_slave;
    bool                                alloc_clock;
    uint8_t                             oversample_value;
    bool                                msb_first;
    cy_stc_scb_spi_context_t            context;
    uint32_t                            irq_cause;
    uint16_t volatile                   pending;
    bool                                op_in_callback;
    uint8_t                             write_fill;
    void                                *rx_buffer;
    uint32_t                            rx_buffer_size;
    const void                          *tx_buffer;
    uint32_t                            tx_buffer_size;
    bool                                is_async;
    cyhal_event_callback_data_t         callback_data;
    bool                                dc_configured;
#else
    void *empty;
#endif
} cyhal_spi_t;

/**
  * @brief SPI configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB)
    const cyhal_resource_inst_t*            resource;
    const cy_stc_scb_spi_config_t*          config;
    const cyhal_clock_t*                    clock;
    struct
    {
        cyhal_gpio_t                        sclk;
        cyhal_gpio_t                        ssel[4];
        cyhal_gpio_t                        mosi;
        cyhal_gpio_t                        miso;
    } gpios;
#else
    void *empty;
#endif /* defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB) */
} cyhal_spi_configurator_t;

/**
  * @brief TDM object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef _cyhal_audioss_t cyhal_tdm_t;

/**
  * @brief TDM configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef _cyhal_audioss_configurator_t cyhal_tdm_configurator_t;

/**
  * @brief Timer object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#ifdef CY_IP_MXTCPWM
    cyhal_tcpwm_t                       tcpwm;
    uint32_t                            default_value;
#else
    void *empty;
#endif
} cyhal_timer_t;

/**
  * @brief Timer configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct
{
#if CYHAL_DRIVER_AVAILABLE_TIMER
    const cyhal_resource_inst_t*            resource;
    const cy_stc_tcpwm_counter_config_t*    config;
    const cyhal_clock_t *                   clock;
#else
    void *empty;
#endif /* CYHAL_DRIVER_AVAILABLE_TIMER */
} cyhal_timer_configurator_t;

/**
  * @brief UART object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB)
    CySCB_Type*                         base;
    cyhal_resource_inst_t               resource;
    cyhal_gpio_t                        pin_rx;
    cyhal_gpio_t                        pin_tx;
    cyhal_gpio_t                        pin_cts;
    cyhal_gpio_t                        pin_rts;
    bool                                cts_enabled;
    bool                                rts_enabled;
    bool                                is_clock_owned;
    cyhal_clock_t                       clock;
    cy_stc_scb_uart_context_t           context;
    cy_stc_scb_uart_config_t            config;
    uint32_t                            irq_cause;
    en_hsiom_sel_t                      saved_tx_hsiom;
    en_hsiom_sel_t                      saved_rts_hsiom;
    cyhal_event_callback_data_t         callback_data;
    bool                                dc_configured;
#else
    void *empty;
#endif
} cyhal_uart_t;

/**
  * @brief UART configurator struct
  *
  * This struct allows a configurator to provide block configuration information
  * to the HAL. Because configurator-generated configurations are platform
  * specific, the contents of this struct is subject to change between platforms
  * and/or HAL releases.
  */
typedef struct {
#if defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB)
    const cyhal_resource_inst_t*            resource;
    const cy_stc_scb_uart_config_t*         config;
    const cyhal_clock_t*                    clock;
    struct
    {
        cyhal_gpio_t                        pin_tx;
        cyhal_gpio_t                        pin_rts;
        cyhal_gpio_t                        pin_cts;
    } gpios;
#else
    void *empty;
#endif /* defined(CY_IP_MXSCB) || defined(CY_IP_MXS22SCB) */
} cyhal_uart_configurator_t;

/**
  * @brief USB Device object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
#ifdef CY_IP_MXUSBFS
    USBFS_Type*                         base;
    cy_stc_usbfs_dev_drv_context_t      context;
    cyhal_resource_inst_t               resource;
    cyhal_resource_inst_t               pll_resource;
    cyhal_clock_t                       clock;
    bool                                shared_clock;
    cyhal_gpio_t                        pin_dp;
    cyhal_gpio_t                        pin_dm;
    cyhal_syspm_callback_data_t         pm_callback;
    uint8_t *rd_data[CY_USBFS_DEV_DRV_NUM_EPS_MAX];
    uint32_t rd_size[CY_USBFS_DEV_DRV_NUM_EPS_MAX];
#else
    void *empty;
#endif
} cyhal_usb_dev_t;

/**
  * @brief WDT object
  *
  * Application code should not rely on the specific contents of this struct.
  * They are considered an implementation detail which is subject to change
  * between platforms and/or HAL releases.
  */
typedef struct {
    uint8_t placeholder;
} cyhal_wdt_t;

#if defined(__cplusplus)
}
#endif /* __cplusplus */

/** \} group_hal_impl_hw_types */
/** \} group_hal_impl */
